www.gusucode.com > VC编写的串口调试软件 > VC编写的串口调试软件,内含Modbus协议类 支持对Modbus通讯调试/Modbus串口调试软件1.0/ModBus.cpp
// ModBus.cpp: implementation of the CModBus class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ModBus.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: LRC------纵向异或校验 //---------------------------------------------------- //参数: const CString& strTxt-------------字符串 //---------------------------------------------------- //功能:纵向异或校验 //---------------------------------------------------- //返回值: // 校验码(1个 char) //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ unsigned char CModBus::LRC(const unsigned char *pucChar, unsigned int unLen) { //在ASCII协议中使用,检测了消息域中除开始的冒号及结束的回车换行号外的内容。 //它仅仅是把每一个需要传输的数据按字节叠加后取反加1即可 unsigned char ucLRC=0; if(0!=unLen%2) return 0; BYTE byLRC = 0; char pBuf[4]; pBuf [2] = '\0'; int nData = 0; for(unsigned int i=0; i<unLen; i+=2) { //每两个需要发送的ASCII码转化为一个十六进制数 pBuf [0] = pucChar[i]; pBuf [1] = pucChar[i+1]; // pBuf [2] = '\0'; sscanf(pBuf,"%x",& nData); byLRC += nData; } byLRC = ~ byLRC; byLRC ++; return byLRC; } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: CRC16------循环容余校验 //---------------------------------------------------- //参数: unsigned char *pucChar-------------接收到的字符 //---------------------------------------------------- //功能: 循环容余校验 //---------------------------------------------------- //返回值: // 校验码 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ unsigned short CModBus::CRC16(const unsigned char *pucChar, unsigned int unLen) { unsigned short usItem=0xA001; unsigned short usCRCReg=0xFFFF; unsigned char ucChar; for(unsigned int i=0;i<unLen;i++) { ucChar=*(pucChar+i); usCRCReg^=ucChar; for(int j=0;j<8;j++) { bool bLSB=((usCRCReg & 0x0001)== 0x0001); usCRCReg=usCRCReg>>1; if(bLSB) { usCRCReg^=usItem; } } } return usCRCReg; // unsigned char uchCRCHi=0xFF; // unsigned char uchCRCLo=0xFF; // unsigned uIndex; // // while(unLen--) // { // uIndex=uchCRCLo^*pucChar++; //calculate the CRC // uchCRCLo=uchCRCHi^auchCRCHi[uIndex]; // uchCRCHi=auchCRCLo[uIndex]; // } // return(uchCRCHi<<8|uchCRCLo); } //Table of CRC Value for high-order byte //unsigned char CModBus::auchCRCHi[]={ // 1 2 3 4 5 6 7 8 9 // 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01 //}; //Table of CRC value for low-order byte //unsigned char CModBus::auchCRCLo[]={ // 0x00,0xC0,0xC1,0x01 //}; CModBus::CModBus() { m_strPrtName="ModBus"; m_unRLen=500; //将要接收字符长度 m_unNowRLen=0; //已经接收字符长度 m_bFrameMode=MODBUS_RTU; // } CModBus::~CModBus() { } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Error------错误提示 //---------------------------------------------------- //参数: int nError-------------错误代码 // int nFunctionCode------功能代码 // int nRegAddr-----------寄存器地址 //---------------------------------------------------- //功能: 错误代码提示 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Error(int nError,int nFunctionCode,int nRegAddr) { CString strErrTip; switch(nError) { case 0x01: strErrTip.Format("从机接收到的功能是不允许的。\n\t功能:%d\t寄存器地址:%d",nFunctionCode,nRegAddr); break; case 0x02: strErrTip.Format("查询中的数据地址对于从机来说是非法的。\n\t功能:%d\t寄存器地址:%d",nFunctionCode,nRegAddr); break; case 0x03: strErrTip.Format("查询中数据域的数值不是从机所允许的。\n\t功能:%d\t寄存器地址:%d",nFunctionCode,nRegAddr); break; case 0x04: strErrTip.Format("当从机试图进行所要求的动作时,发生了一个不可恢复的错误。\n\t功能:%d\t寄存器地址:%d",nFunctionCode,nRegAddr); break; case 0x05: strErrTip.Format("从机已接受查询,正在进行处理,但需要持续较长的时间。\n\t功能:%d\t寄存器地址:%d",nFunctionCode,nRegAddr); break; case 0x06: strErrTip.Format("从机正在处理一个持续时间比较长的指令。\n\t功能:%d\t寄存器地址:%d",nFunctionCode,nRegAddr); break; case 0x07: strErrTip.Format("从机不能完成查询中的功能要求。\n\t功能:%d\t寄存器地址:%d",nFunctionCode,nRegAddr); break; case 0x08: strErrTip.Format("从机试图阅读扩展存储器,但在存储器中发现奇偶校验错误。\n\t功能:%d\t寄存器地址:%d",nFunctionCode,nRegAddr); break; default: strErrTip.Format("不可知的错误。\n\t功能:%d\t寄存器地址:%d",nFunctionCode,nRegAddr); } throw(strErrTip); } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: ReceiveByte------接收字符 //---------------------------------------------------- //参数: unsigned char& ch-------------接收到的字符 //---------------------------------------------------- //功能: 接收字符处理 //---------------------------------------------------- //返回值: // 0------正在接收记录 // 1------字符接收完毕 // 2------要求重发送一次 // 3------校验错误,要求重发一次 // 4------没有数据处理 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ int CModBus::ReceiveByte(unsigned char& ch) { if (NULL==m_pComData) return 4; //数据为空 //-------------------------------------------------- m_ucRData[m_unNowRLen++]=ch; if(MODBUS_RTU==m_bFrameMode) return ReceiveByte_RTU(ch); else //ASCII { return ReceiveByte_ASCII(ch); } } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Transform------转换成十进制、十六进制、二进制 //---------------------------------------------------- //参数: unsigned char &pChar-------------数据数组 // unsigned int unLen---------------数据长度 // unsigned int unType--------------将要转换的类型1:整形;2:十六进制;3:二进制位 //---------------------------------------------------- //功能: 对发送数据进行译码 //---------------------------------------------------- //返回值: // NULL //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //DEL CString CModBus::Transform(const unsigned char* pChar, unsigned int unLen, unsigned int unType) //DEL { //DEL CString strTxt; //DEL switch(unType) //DEL { //DEL case 1: //DEL { //DEL strTxt.Empty (); //DEL for(unsigned int nIndex=0;nIndex<unLen;nIndex++) //DEL strTxt+=(char*)pChar[nIndex]; //DEL break; //DEL } //DEL case 2: //DEL { //DEL strTxt.Empty (); //DEL for(unsigned int nIndex=0;nIndex<unLen;nIndex++) //DEL strTxt+=(char*)pChar[nIndex]; //DEL int nNum=atoi(strTxt); //DEL strTxt.Format ("%x",nNum); //DEL strTxt.MakeUpper (); //DEL if(strTxt.GetLength ()==1) //DEL { //DEL strTxt.Insert (0,"0"); //DEL } //DEL //DEL break; //DEL } //DEL case 3: //DEL { //DEL for(unsigned int i=0;i<unLen;i++) //DEL { //DEL unsigned char ch=*(pChar+i); //DEL for(unsigned int j=0;j<8;j++) //DEL { //DEL bool bBit=((ch>>i & 0x0001)== 0x0001); //DEL if(bBit) //DEL strTxt+="1"; //DEL else //DEL strTxt+="0"; //DEL } //DEL } //DEL break; //DEL } //DEL } //DEL //DEL return strTxt; //DEL } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Decoding------译码 //---------------------------------------------------- //参数: CComData& Data-------------数据结构 //---------------------------------------------------- //功能: 对发送数据进行译码 //---------------------------------------------------- //返回值: // NULL //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Decoding(CComData& Data) //协议译码 { // m_unRLen=0; //将要接收字符长度 m_unNowRLen=0; //已经接收字符长度 // if (NULL==&Data) { m_pComData=NULL; return ; //数据为空 } m_pComData=&Data; if(m_pComData->m_bTranstation && m_pComData->m_bReadWrite) { return; } //1、从站地址 if(m_pComData->m_unStationNum>256) throw("ModBus----站号>256"); //-------------------------------------------------------- //RTU 模式 if(MODBUS_RTU==m_bFrameMode) { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | CRC CHECK | END //--------------------------------------------------------------------------------- //T1–T2–T3–T4 | 8 BITS | 8 BITS |n x 8 BITS | 16 BITS |T1–T2–T3–T4 //--------------------------------------------------------------------------------- Decoding_RTU(Data); } else //MODBUS_ASCII { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | LRC | CHECK | END //--------------------------------------------------------------------------------- // 1 CHAR: | 2 CHARS | 2 CHARS | n CHARS | 2 CHARS | 2 CHARS | CRLF //--------------------------------------------------------------------------------- Decoding_ASCII(Data); } } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_RTU_ReadCoils------处理发送字符 //(读取单个/多个线圈DO) 功能代码:0x01 //---------------------------------------------------- //参数: CComData& Data-------------发送数据 //---------------------------------------------------- //功能: 对发送数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_RTU_ReadCoils(CComData& Data) { //1、功能代码 m_pComData->m_ucProtocalTxt[1]=0x01; //2、起始地址 unsigned short usRegAddr=m_pComData->m_unRegAddr; m_pComData->m_ucProtocalTxt[2]=(usRegAddr>>8)&0x00FF; m_pComData->m_ucProtocalTxt[3]=usRegAddr&0x00FF; //4、读写寄存器数量 unsigned short usCount=(unsigned short) Data.m_unRegCount; if (0==usCount) usCount=1; m_pComData->m_ucProtocalTxt[4]=0x00FF & (usCount>>8); m_pComData->m_ucProtocalTxt[5]=0x00FF & usCount; //5、数据长度 //--------------------------------------------------------- //1Byte 站号 //--------------------------------------------------------- //1Byte Function Code //2Byte Starting Address(0x0000 to 0xFFFF) //2Byte Quantity of coils(1 to 2000(0x7D0)) //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- m_pComData->m_unDataLen=8; //2(CRC16) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_RTU_ReadDiscreteInputs------处理发送字符 //(读取单个/多个接触器DI) //功能代码:0x02 //---------------------------------------------------- //参数: CComData& Data-------------发送数据 //---------------------------------------------------- //功能: 对发送数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_RTU_ReadDiscreteInputs(CComData& Data) { //1、功能代码 m_pComData->m_ucProtocalTxt[1]=0x02; //2、起始地址 unsigned short usRegAddr=m_pComData->m_unRegAddr; m_pComData->m_ucProtocalTxt[2]=(usRegAddr>>8)&0x00FF; m_pComData->m_ucProtocalTxt[3]=usRegAddr&0x00FF; //4、读写寄存器数量 unsigned short usCount=Data.m_unRegCount; if (0==usCount) usCount=1; m_pComData->m_ucProtocalTxt[4]=0x00FF & (usCount>>8); m_pComData->m_ucProtocalTxt[5]=0x00FF & usCount; //5、数据长度 //--------------------------------------------------------- //1Byte 站号 //--------------------------------------------------------- //1Byte Function Code //2Byte Starting Address(0x0000 to 0xFFFF) //2Byte Quantity of Inputs(1 to 2000(0x7D0)) //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- m_pComData->m_unDataLen=8; //2(CRC16) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_RTU_ReadHoldingRegisters------处理发送字符 //(读取单个/多个保持寄存器) //功能代码:0x03 //---------------------------------------------------- //参数: CComData& Data-------------发送数据 //---------------------------------------------------- //功能: 对发送数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_RTU_ReadHoldingRegisters(CComData& Data) { //1、功能代码 m_pComData->m_ucProtocalTxt[1]=0x03; //2、起始地址 unsigned short usRegAddr=m_pComData->m_unRegAddr; m_pComData->m_ucProtocalTxt[2]=(usRegAddr>>8)&0x00FF; m_pComData->m_ucProtocalTxt[3]=usRegAddr & 0x00FF; //4、读写寄存器数量 unsigned short usCount=Data.m_unRegCount; if (0==usCount) usCount=1; m_pComData->m_ucProtocalTxt[4]=0x00FF & (usCount>>8); m_pComData->m_ucProtocalTxt[5]=0x00FF & usCount; //5、数据长度 //--------------------------------------------------------- //1Byte 站号 //--------------------------------------------------------- //1Byte Function Code //2Byte Starting Address(0x0000 to 0xFFFF) //2Byte Quantity of Registers(1 to 125(0x7D)) //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- m_pComData->m_unDataLen=8; //2(CRC16) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_RTU_ReadInputRegisters------处理接收字符 //(读取单个、多个寄存器) //功能代码:0x04 //---------------------------------------------------- //参数: CComData& Data-------------发送的数据 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_RTU_ReadInputRegisters(CComData& Data) { //1、功能代码 m_pComData->m_ucProtocalTxt[1]=0x04; //2、起始地址 unsigned short usRegAddr=m_pComData->m_unRegAddr; m_pComData->m_ucProtocalTxt[2]=(usRegAddr>>8)&0x00FF; m_pComData->m_ucProtocalTxt[3]=usRegAddr & 0x00FF; //4、读写寄存器数量 unsigned short usCount=(unsigned short)Data.m_unRegCount; if (0==usCount) usCount=1; m_pComData->m_ucProtocalTxt[4]=0x00FF & (usCount>>8); m_pComData->m_ucProtocalTxt[5]=0x00FF & usCount; //5、数据长度 //--------------------------------------------------------- //1Byte 站号 //--------------------------------------------------------- //1Byte Function Code //2Byte Starting Address(0x0000 to 0xFFFF) //2Byte Quantity of Input Registers(1 to 125(0x7D)) //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- m_pComData->m_unDataLen=8; //2(CRC16) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_RTU_WriteSingleCoil------处理接收字符 //(写单个线圈) //功能代码:0x05 //---------------------------------------------------- //参数: CComData& Data-------------发送的数据 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_RTU_WriteSingleCoil(CComData& Data) { //1、功能代码 m_pComData->m_ucProtocalTxt[1]=0x05; //2、起始地址 unsigned short usRegAddr=m_pComData->m_unRegAddr; m_pComData->m_ucProtocalTxt[2]=(usRegAddr>>8) & 0x00FF; m_pComData->m_ucProtocalTxt[3]=usRegAddr & 0x00FF; //4、写入值 unsigned short usValue=(unsigned short) atoi(Data.m_strRegValue); if(usValue==1) { //ON m_pComData->m_ucProtocalTxt[4]=0xFF; m_pComData->m_ucProtocalTxt[5]=0x00; } else { //OFF m_pComData->m_ucProtocalTxt[4]=0x00; m_pComData->m_ucProtocalTxt[5]=0x00; } //5、数据长度 //--------------------------------------------------------- //1Byte 站号 //--------------------------------------------------------- //1Byte Function Code(0x05) //2Byte Output Address(0x0000 to 0xFFFF) //2Byte Output Value(0x0000 or 0xFF00) //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- m_pComData->m_unDataLen=8; //2(CRC16) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_RTU_WriteSingleRegister------处理接收字符 //(写单个寄存器) //功能代码:0x06 //---------------------------------------------------- //参数: CComData& Data-------------发送的数据 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_RTU_WriteSingleRegister(CComData& Data) { //1、功能代码 m_pComData->m_ucProtocalTxt[1]=0x06; //2、起始地址 unsigned short usRegAddr=m_pComData->m_unRegAddr; m_pComData->m_ucProtocalTxt[2]=(usRegAddr>>8) & 0x00FF; m_pComData->m_ucProtocalTxt[3]=usRegAddr & 0x00FF; //4、写入值-----------注意负数???? unsigned short usCount=(unsigned short) atoi(Data.m_strRegValue); //对于整数负数没有问题 m_pComData->m_ucProtocalTxt[4]=0x00FF & (usCount>>8); m_pComData->m_ucProtocalTxt[5]=0x00FF & usCount; //5、数据长度 //--------------------------------------------------------- //1Byte 站号 //--------------------------------------------------------- //1Byte Function Code(0x05) //2Byte Register Address(0x0000 to 0xFFFF) //2Byte Register Value(0x0000 or 0xFF00) //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- m_pComData->m_unDataLen=8; } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_RTU_WriteMultipleCoils------处理接收字符 //(写多个线圈) //功能代码:0x0F //---------------------------------------------------- //参数: CComData& Data-------------发送的数据 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_RTU_WriteMultipleCoils(CComData& Data) {//只支持单个线圈写----调试未成功 //1、功能代码 m_pComData->m_ucProtocalTxt[1]=0x0F; //2、起始地址 unsigned short usRegAddr=m_pComData->m_unRegAddr; m_pComData->m_ucProtocalTxt[2]=(usRegAddr>>8) & 0x00FF; m_pComData->m_ucProtocalTxt[3]=usRegAddr & 0x00FF; //4、读写寄存器数量 unsigned short usCount=(unsigned short) Data.m_unRegCount; if (0==usCount) usCount=1; m_pComData->m_ucProtocalTxt[4]=0x00FF & (usCount>>8); m_pComData->m_ucProtocalTxt[5]=0x00FF & usCount; //5、数据字节数 unsigned int unLen=m_pComData->m_strRegValue.GetLength (); unsigned int unMod=unLen%8; unsigned int unByteCount=unLen/8+(unMod>0 ? 1:0); m_pComData->m_ucProtocalTxt[6]=unByteCount+1; //6、写入值 int nIndex=6+1; m_pComData->m_ucProtocalTxt[nIndex++]=1; m_pComData->m_ucProtocalTxt[nIndex++]=0; /* m_pComData->m_strRegValue;//存放的是01010101 for(unsigned int unByte=0;unByte<unByteCount;unByte++) { char cByte=0x00; for(unsinged int unIndex=0;unIndex<8;unIndex++) { cByte|= } m_pComData->m_ucProtocalTxt[nIndex++]=ucByte4H<<4 | ucByte4L; } //*/ //7、数据长度 //--------------------------------------------------------- //1Byte 站号 //--------------------------------------------------------- //1Byte Function Code(0x0F) //2Byte Register Address(0x0000 to 0xFFFF) //2Byte Quantity of Outputs(0x0000 or 0x07B0) //1Byte Byte Count //N$ *1 Byte Outputs Value(N$=Quantity of Outputs/8,if then remainder if different of 0=>N=N+1) //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- m_pComData->m_unDataLen=7+unByteCount+2+1; } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_RTU_WriteMultipleRegisters------处理接收字符(写多个寄存器) //功能代码:0x10 //---------------------------------------------------- //参数: CComData& Data-------------发送的数据 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_RTU_WriteMultipleRegisters(CComData& Data) //pass debug 20040213 {//只支持单字 //1、功能代码 m_pComData->m_ucProtocalTxt[1]=0x10; //2、起始地址 unsigned short usRegAddr=m_pComData->m_unRegAddr; m_pComData->m_ucProtocalTxt[2]=(usRegAddr>>8) & 0x00FF; m_pComData->m_ucProtocalTxt[3]=usRegAddr & 0x00FF; //4、写寄存器数量 unsigned short usCount=(unsigned short) Data.m_unRegCount; if (0==usCount) usCount=1; m_pComData->m_ucProtocalTxt[4]=0x00FF & (usCount>>8); m_pComData->m_ucProtocalTxt[5]=0x00FF & usCount; //5、数据字节数 m_pComData->m_ucProtocalTxt[6]=2*usCount; //6、写入值 int nIndex=6+1; // unsigned short usValue=(unsigned short) atoi(m_pComData->m_strRegValue); //对于整数负数没有问题 // m_pComData->m_ucProtocalTxt[nIndex++]=0x00FF & (usValue>>8); // m_pComData->m_ucProtocalTxt[nIndex]=0x00FF & usValue; m_pComData->m_strRegValue.MakeUpper(); unsigned int unLen=m_pComData->m_strRegValue .GetLength (); //存放的是十六进制数 for(unsigned int unIndex=0;unIndex<unLen;unIndex+=2) { char cByte[2]; // CString str=m_pComData->m_strRegValue.Mid (unIndex,2); // strcpy((LPTSTR)(LPCTSTR)m_pComData->m_strRegValue.Mid (unIndex,2),cByte); strcpy(cByte,str); unsigned char ucByte4H=(unsigned char)cByte[0]; unsigned char ucByte4L=(unsigned char)cByte[1]; if(ucByte4H>=unsigned char('A')) ucByte4H-='A'; else ucByte4H-='0'; if(ucByte4L>='A') ucByte4L-='A'; else ucByte4L-='0'; m_pComData->m_ucProtocalTxt[nIndex++]=ucByte4H<<4 | ucByte4L; } //*/ //7、数据长度 //--------------------------------------------------------- //1Byte 站号 //--------------------------------------------------------- //1Byte Function Code(0x10) //2Byte Register Address(0x0000 to 0xFFFF) //2Byte Quantity of Outputs(0x0000 or 0x07B0) //1Byte Byte Count(2*N$) //N$ *2 Byte Outputs Value(N$=Quantity of Registers) //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- m_pComData->m_unDataLen=7+usCount*2+2; } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Response_RTU_ReadDiscreteInputs------处理接收字符 //---------------------------------------------------- //参数: unsigned char &ch-------------接收到的字符(读取单个/多个接触器DI) //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // 0------正在接收记录 // 1------字符接收完毕 // 2------要求重发送一次 // 3------校验错误,要求重发一次 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ int CModBus::Response_RTU_ReadDiscreteInputs(unsigned char &ch) { //Read_DI if(1==m_unNowRLen-1) //功能代码 { m_ucRFunctionCode=ch; return 0; } else if(2==m_unNowRLen-1) //已经接收字符长度 {//接收到的第一个字符 if(0x02==m_ucRFunctionCode) { m_unRLen=3+ch+2; //将要接收字符长度==站号(1)+功能代码(1)+数量(1)+数据(N+1)+校验(2) return 0; } else if(0x82==m_ucRFunctionCode) {//返回错误----Error=0x01 or 0x02 or 0x03 or 0x04 Error(ch,0x02,m_pComData->m_unRegAddr); return ch; } else {//返回错误----功能代号错误 Error(ch,0x02,m_pComData->m_unRegAddr); return 0; } } if(m_unNowRLen==m_unRLen-1) //字符接收完毕 { m_usRCheck=ch; } else if(m_unNowRLen==m_unRLen) //字符接收完毕 { m_usRCheck |=ch<<8; //进行容余校验 unsigned short usCheckCRC16=CRC16(&m_ucRData[0],m_unRLen-2); if(usCheckCRC16==m_usRCheck) { //数据传输正确 if(1==m_ucRData[2]) //单个点 // m_pComData->Transform(&m_ucRData[3],1,true); m_pComData->Transform(&m_ucRData[3],1); else Response_RTU_MVaule(3,m_unRLen-2); //需要转换 return 1; } else { //校验码错误 Error(ch,0x02,m_pComData->m_unRegAddr); return 3; } } return 0; //--------------------------------------------------------- //--------------------------------------------------------- //1Byte Function Code(0x01) //1Byte Byte count N$ //nByte Coil Status (n=N or N+1)[N$=Quantity of Outputs/8,if the remainder is different of 0=>N=N=1; //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Response_RTU_ReadCoils------处理接收字符 //---------------------------------------------------- //参数: unsigned char &ch-------------接收到的字符(读取单个/多个线圈DO) //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // 0------正在接收记录 // 1------字符接收完毕 // 2------要求重发送一次 // 3------校验错误,要求重发一次 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ int CModBus::Response_RTU_ReadCoils(unsigned char &ch) { //Read_DO if(1==m_unNowRLen-1) { m_ucRFunctionCode=ch; return 0; } else if(2==m_unNowRLen-1) //已经接收字符长度 {//接收到的第一个字符 if(0x01==m_ucRFunctionCode) { m_unRLen=3+ch+2; //将要接收字符长度=站号(1)+功能代码(1)+数量(1)+数据(N)+校验(2) return 0; } else if(0x81==m_ucRFunctionCode) {//返回错误----Error=0x01 or 0x02 or 0x03 or 0x04 Error(ch,0x01,m_pComData->m_unRegAddr); return ch; } else {//返回错误----功能代号错误 Error(ch,0x01,m_pComData->m_unRegAddr); return 0; } } //校验码 if(m_unNowRLen==m_unRLen-1) //字符接收完毕 { m_usRCheck=ch; //校验码[1 High Byte] } else if(m_unNowRLen==m_unRLen) //字符接收完毕 { m_usRCheck |=ch<<8; //校验码[2 Low Byte] //进行容余校验 unsigned short usCheckCRC16=CRC16(&m_ucRData[0],m_unRLen-2); if(usCheckCRC16==m_usRCheck) { //数据传输正确 if(1==m_ucRData[2]) //单个点 // m_pComData->Transform(&m_ucRData[3],1,true); m_pComData->Transform(&m_ucRData[3],1); else Response_RTU_MVaule(3,m_unRLen-2); //需要转换 return 1; } else { //校验码错误 Error(ch,0x01,m_pComData->m_unRegAddr); return 3; } } return 0; //--------------------------------------------------------- //--------------------------------------------------------- //1Byte Function Code(0x01) //1Byte Byte count N$ //nByte Coil Status (n=N or N+1)[N$=Quantity of Outputs/8,if the remainder is different of 0=>N=N=1; //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Response_RTU_ReadHoldingRegisters------处理接收字符(读取单个/多个保持寄存器) //---------------------------------------------------- //参数: unsigned char &ch-------------接收到的字符 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // 0------正在接收记录 // 1------字符接收完毕 // 2------要求重发送一次 // 3------校验错误,要求重发一次 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ int CModBus::Response_RTU_ReadHoldingRegisters(unsigned char& ch) { if(1==m_unNowRLen-1) //功能代码 { m_ucRFunctionCode=ch; return 0; } else if(2==m_unNowRLen-1) //已经接收字符长度 {//接收到的第一个字符 if(0x03==m_ucRFunctionCode) { m_unRLen=3+ch+2; //将要接收字符长度==站号(1)+功能代码(1)+数量(1)+数据(2*N=ch)+校验(2) return 0; } else if(0x83==m_ucRFunctionCode) {//返回错误----Error=0x01 or 0x02 or 0x03 or 0x04 Error(ch,0x03,m_pComData->m_unRegAddr); return ch; } else {//返回错误----功能代号错误 Error(ch,0x03,m_pComData->m_unRegAddr); return 0; } } if(m_unNowRLen==m_unRLen-1) //字符接收完毕 { m_usRCheck=ch; } else if(m_unNowRLen==m_unRLen) //字符接收完毕 { m_usRCheck |=ch<<8; //进行容余校验 unsigned short usCheckCRC16=CRC16(&m_ucRData[0],m_unRLen-2); if(usCheckCRC16==m_usRCheck) { //数据传输正确 if(2==m_ucRData[2]) //单个点 // m_pComData->Transform(&m_ucRData[3],2,true); m_pComData->Transform(&m_ucRData[3],2); else Response_RTU_MVaule(3,m_unRLen-2); //需要转换 return 1; } else { //校验码错误 Error(ch,0x03,m_pComData->m_unRegAddr); return 3; } } return 0; //--------------------------------------------------------- //--------------------------------------------------------- //1Byte Function Code(0x01) //1Byte Byte count N$ //nByte Coil Status (n=N or N+1)[N$=Quantity of Outputs/8,if the remainder is different of 0=>N=N=1; //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Response_RTU_ReadInputRegisters------处理接收字符(读取单个/多个输入寄存器) //--------------------------------------------------------------------------------- //参数: unsigned char &ch-------------接收到的字符 //--------------------------------------------------------------------------------- //功能: 对接收到的数据进行译码 //--------------------------------------------------------------------------------- //返回值: // 0------正在接收记录 // 1------字符接收完毕 // 2------要求重发送一次 // 3------校验错误,要求重发一次 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ int CModBus::Response_RTU_ReadInputRegisters(unsigned char& ch) { if(1==m_unNowRLen-1) //功能代码 { m_ucRFunctionCode=ch; return 0; } else if(2==m_unNowRLen-1) //已经接收字符长度 {//接收到的第一个字符 if(0x04==m_ucRFunctionCode) { m_unRLen=3+ch+2; //将要接收字符长度==功能代码(1)+数量(1)+数据(N+1)+校验(2) return 0; } else if(0x84==m_ucRFunctionCode) {//返回错误----Error=0x01 or 0x02 or 0x03 or 0x04 Error(ch,0x03,m_pComData->m_unRegAddr); return ch; } else {//返回错误----功能代号错误 Error(ch,0x03,m_pComData->m_unRegAddr); return 0; } } if(m_unNowRLen==m_unRLen-1) //字符接收完毕 { m_usRCheck=ch; } else if(m_unNowRLen==m_unRLen) //字符接收完毕 { m_usRCheck |=ch<<8; //进行容余校验 unsigned short usCheckCRC16=CRC16(&m_ucRData[0],m_unRLen-2); if(usCheckCRC16==m_usRCheck) { //数据传输正确 if(2==m_ucRData[2]) //单个点 // m_pComData->Transform(&m_ucRData[3],2,true); m_pComData->Transform(&m_ucRData[3],2); else { Response_RTU_MVaule(3,m_unRLen-2); //需要转换 } return 1; } else { //校验码错误 Error(ch,0x03,m_pComData->m_unRegAddr); return 3; } } return 0; //--------------------------------------------------------- //--------------------------------------------------------- //1Byte Function Code(0x01) //1Byte Byte count N$ //nByte Coil Status (n=N or N+1)[N$=Quantity of Outputs/8,if the remainder is different of 0=>N=N=1; //--------------------------------------------------------- //2Byte CRC16 //--------------------------------------------------------- } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Response_RTU_WriteSingleCoil------处理接收字符(写单个线圈) //---------------------------------------------------- //参数: unsigned char &ch-------------接收到的字符 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // 0------正在接收记录 // 1------字符接收完毕 // 2------要求重发送一次 // 3------校验错误,要求重发一次 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ int CModBus::Response_RTU_WriteSingleCoil(unsigned char& ch) { if(1==m_unNowRLen-1) { m_ucRFunctionCode=ch; return 0; } else if(2==m_unNowRLen-1) //已经接收字符长度 {//接收到的第一个字符 if(0x05==m_ucRFunctionCode) { m_unRLen=8; //将要接收字符长度=站号(1)+功能代码(1)+地址(2)+数据(2)+校验(2) return 0; } else if(0x85==m_ucRFunctionCode) {//返回错误----Error=0x01 or 0x02 or 0x03 or 0x04 Error(ch,0x01,m_pComData->m_unRegAddr); return ch; } else {//返回错误----功能代号错误 Error(ch,0x01,m_pComData->m_unRegAddr); return 0; } } //校验码 if(m_unNowRLen==m_unRLen-1) //字符接收完毕 { m_usRCheck=ch; } else if(m_unNowRLen==m_unRLen) //字符接收完毕 { m_usRCheck |=ch<<8; //进行容余校验 unsigned short usCheckCRC16=CRC16(&m_ucRData[0],m_unRLen-2); if(usCheckCRC16==m_usRCheck) {//接收完毕 for(unsigned int nIndex=0;nIndex<m_unRLen;nIndex++) { if(m_ucRData[nIndex]!=m_pComData->m_ucProtocalTxt[nIndex]) return 3; } return 1; } } return 0; } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Response_RTU_WriteMultipleCoils------处理接收字符(写多个线圈) //---------------------------------------------------- //参数: unsigned char &ch-------------接收到的字符 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // 0------正在接收记录 // 1------字符接收完毕 // 2------要求重发送一次 // 3------校验错误,要求重发一次 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ int CModBus::Response_RTU_WriteSingleRegister(unsigned char& ch) { if(1==m_unNowRLen-1) { m_ucRFunctionCode=ch; return 0; } else if(2==m_unNowRLen-1) //已经接收字符长度 {//接收到的第一个字符 if(0x06==m_ucRFunctionCode) { m_unRLen=8; //将要接收字符长度=站号(1)+功能代码(1)+地址(2)+数据(2)+校验(2) return 0; } else if(0x86==m_ucRFunctionCode) {//返回错误----Error=0x01 or 0x02 or 0x03 or 0x04 Error(ch,0x01,m_pComData->m_unRegAddr); return ch; } else {//返回错误----功能代号错误 Error(ch,0x01,m_pComData->m_unRegAddr); return 0; } } //校验码 if(m_unNowRLen==m_unRLen-1) //字符接收完毕 { m_usRCheck=ch; } else if(m_unNowRLen==m_unRLen) //字符接收完毕 { m_usRCheck |=ch<<8; //进行容余校验 unsigned short usCheckCRC16=CRC16(&m_ucRData[0],m_unRLen-2); if(usCheckCRC16==m_usRCheck) {//接收完毕 for(unsigned int nIndex=0;nIndex<m_unRLen;nIndex++) { if(m_ucRData[nIndex]!=m_pComData->m_ucProtocalTxt[nIndex]) return 3; } return 1; } } return 0; } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Response_RTU_WriteMultipleCoils------处理接收字符(写多个线圈) //---------------------------------------------------- //参数: unsigned char &ch-------------接收到的字符 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // 0------正在接收记录 // 1------字符接收完毕 // 2------要求重发送一次 // 3------校验错误,要求重发一次 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ int CModBus::Response_RTU_WriteMultipleCoils(unsigned char& ch) { if(1==m_unNowRLen-1) { m_ucRFunctionCode=ch; return 0; } else if(2==m_unNowRLen-1) //已经接收字符长度 {//接收到的第一个字符 if(0x0F==m_ucRFunctionCode) { m_unRLen=8; //将要接收字符长度=功能代码(1)+数量(1)+数据(N+1)+校验(2) return 0; } else if(0x8F==m_ucRFunctionCode) {//返回错误----Error=0x01 or 0x02 or 0x03 or 0x04 Error(ch,0x01,m_pComData->m_unRegAddr); return ch; } else {//返回错误----功能代号错误 Error(ch,0x01,m_pComData->m_unRegAddr); return 0; } } //校验码 if(m_unNowRLen==m_unRLen-1) //字符接收完毕 { m_usRCheck=ch; } else if(m_unNowRLen==m_unRLen) //字符接收完毕 { m_usRCheck |=ch<<8; //进行容余校验 unsigned short usCheckCRC16=CRC16(&m_ucRData[0],m_unRLen-2); if(usCheckCRC16==m_usRCheck) {//接收完毕 //接收数据错误,要求重发 for(unsigned int nIndex=2;nIndex<6;nIndex++) { if(m_ucRData[nIndex]!=m_pComData->m_ucProtocalTxt[nIndex]) return 2; } return 1; } } return 0; } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Response_RTU_WriteMultipleRegisters------处理接收字符(写多个寄存器) //---------------------------------------------------- //参数: unsigned char &ch-------------接收到的字符 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // 0------正在接收记录 // 1------字符接收完毕 // 2------要求重发送一次 // 3------校验错误,要求重发一次 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ int CModBus::Response_RTU_WriteMultipleRegisters(unsigned char& ch) //通过调试20040221 { // if(1==m_unNowRLen-1) { m_ucRFunctionCode=ch; return 0; } else if(2==m_unNowRLen-1) //已经接收字符长度 {//接收到的第一个字符 if(0x10==m_ucRFunctionCode) { m_unRLen=8; //将要接收字符长度=站号(1)+功能代码(1)+地址(2)+数量(2)+校验(2) return 0; } else if(0x90==m_ucRFunctionCode) {//返回错误----Error=0x01 or 0x02 or 0x03 or 0x04 Error(ch,0x01,m_pComData->m_unRegAddr); return ch; } else {//返回错误----功能代号错误 Error(ch,0x01,m_pComData->m_unRegAddr); return 0; } } //校验码 if(m_unNowRLen==m_unRLen-1) //字符接收完毕 { m_usRCheck=ch; } else if(m_unNowRLen==m_unRLen) //字符接收完毕 { m_usRCheck |=ch<<8; //进行容余校验 unsigned short usCheckCRC16=CRC16(&m_ucRData[0],m_unRLen-2); if(usCheckCRC16==m_usRCheck) {//接收完毕 //接收数据错误,要求重发 for(unsigned int nIndex=2;nIndex<6;nIndex++) { if(m_ucRData[nIndex]!=m_pComData->m_ucProtocalTxt[nIndex]) return 2; } return 1; } } return 0; } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Response_RTU_MVaule------处理读取多个数据 //---------------------------------------------------- //参数: int nStart-------------从接收缓冲区的开始位置 // int nLen---------------接收缓冲区的有效数据长度 //---------------------------------------------------- //功能: 对接收到的数据进行译码,存入数据结构中 //---------------------------------------------------- //返回值: //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Response_RTU_MVaule(int nStart, int nEnd) { //十六使用进制ASC码(HexAsc)方式 m_pComData->m_strRegValue.Empty (); for (;nStart<nEnd;nStart++) { char cT[2]; char cV=0; cT[0]=m_ucRData[nStart]>>4; cT[1]=m_ucRData[nStart]&0x0F; for(int j=0;j<2;j++) { if(cT[j]>9) cV='A'+cT[j]-0xA; else cV='0'+cT[j]; m_pComData->m_strRegValue.Insert (m_pComData->m_strRegValue.GetLength (),cV); } } } void CModBus::Init() { m_unNowRLen=0; //已经接收字符长度 if(m_pComData) m_pComData->m_unRcvLen =0; } void CModBus::SetFrameMode(BOOL bFrameMode/*=CModBus::MODBUS_RTU*/) { m_bFrameMode=bFrameMode; //通讯模式:MODBUS_RTU,MODBUS_ASCII } BOOL CModBus::GetFrameMode() { return m_bFrameMode; //通讯模式:MODBUS_RTU,MODBUS_ASCII } void CModBus::Decoding_RTU(CComData &Data) { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | CRC CHECK | END //--------------------------------------------------------------------------------- //T1–T2–T3–T4 | 8 BITS | 8 BITS |n x 8 BITS | 16 BITS |T1–T2–T3–T4 //--------------------------------------------------------------------------------- //--------------------------------------------------------- //1.站号(1Byte) //--------------------------------------------------------- m_pComData->m_ucProtocalTxt[0]=m_pComData->m_unStationNum; //--------------------------------------------------------- //2.Modbus 数据帧 //--------------------------------------------------------- // //--------------------------------------------------------- //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | CRC CHECK | END //--------------------------------------------------------------------------------- //T1–T2–T3–T4 | 8 BITS | 8 BITS |n x 8 BITS | 16 BITS |T1–T2–T3–T4 //--------------------------------------------------------------------------------- //2、协议数据单元 switch(m_pComData->m_unRegType) { case 1: { Query_RTU_ReadCoils(Data); break; } case 2: { Query_RTU_ReadDiscreteInputs(Data); break; } case 3: { Query_RTU_ReadHoldingRegisters(Data); break; } case 4: { Query_RTU_ReadInputRegisters(Data); break; } case 5: { Query_RTU_WriteSingleCoil(Data); break; } case 6: { Query_RTU_WriteSingleRegister(Data); break; } case 15: { Query_RTU_WriteMultipleCoils(Data); break; } case 16: { Query_RTU_WriteMultipleRegisters(Data); break; } default: { //功能代码错误 // throw("ModBus----功能代码错误"); } } //3、进行RCR16校验 //-------------------------------------------------------- unsigned short usCRC16; /* //Sample m_pComData->m_ucProtocalTxt[0]=0x02; m_pComData->m_ucProtocalTxt[1]=0x07; usCRC16=CRC16(&m_pComData->m_ucProtocalTxt[0],2); //*/ usCRC16=CRC16(&m_pComData->m_ucProtocalTxt[0],m_pComData->m_unDataLen-2); m_pComData->m_ucProtocalTxt[m_pComData->m_unDataLen-1]=(usCRC16>>8)&0x00ff; //高字节---在后 m_pComData->m_ucProtocalTxt[m_pComData->m_unDataLen-2]=usCRC16&0x00ff; //低字节---在前 } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Decoding_ASCII------将数据翻译为Modbus ASCII 格式 // //---------------------------------------------------- //参数: //---------------------------------------------------- //功能: 将数据翻译为Modbus ASCII 通讯格式 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Decoding_ASCII(CComData &Data) { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | LRC | CHECK | END //--------------------------------------------------------------------------------- // 1 CHAR: | 2 CHARS | 2 CHARS | n CHARS | 2 CHARS | 2 CHARS | CRLF //--------------------------------------------------------------------------------- //--------------------------------------------------------- //1.头(1Byte)---[数据帧Header] //--------------------------------------------------------- m_pComData->m_ucProtocalTxt[0]=(unsigned char)':'; //--------------------------------------------------------- //2.站号(2Byte) //--------------------------------------------------------- ToHexAscII((unsigned char)m_pComData->m_unStationNum, m_pComData->m_ucProtocalTxt[1]); //--------------------------------------------------------- //3. Modbus 数据帧 //--------------------------------------------------------- //2Byte Function Code //4Byte Starting Address(0x0000 to 0xFFFF) //4Byte Quantity of coils(1 to 2000(0x7D0)) //--------------------------------------------------------- //协议数据单元 switch(m_pComData->m_unRegType) { case 1: { Query_ASCII_ReadCoils(Data); break; } case 2: { Query_ASCII_ReadDiscreteInputs(Data); break; } case 3: { Query_ASCII_ReadHoldingRegisters(Data); break; } case 4: { Query_ASCII_ReadInputRegisters(Data); break; } case 5: { Query_ASCII_WriteSingleCoil(Data); break; } case 6: { Query_ASCII_WriteSingleRegister(Data); break; } case 15: { Query_ASCII_WriteMultipleCoils(Data); break; } case 16: { Query_ASCII_WriteMultipleRegisters(Data); break; } default: { //功能代码错误 // throw("ModBus----功能代码错误"); } } //--------------------------------------------------------- //4.校验 LRC(2Byte) //--------------------------------------------------------- unsigned char ucLRC=LRC(&m_pComData->m_ucProtocalTxt[1], m_pComData->m_unDataLen-5); ToHexAscII(ucLRC, m_pComData->m_ucProtocalTxt[m_pComData->m_unDataLen-4]); //--------------------------------------------------------- //5.END-- CR LF(2Byte) //--------------------------------------------------------- m_pComData->m_ucProtocalTxt[m_pComData->m_unDataLen-2]=0x0D; //CR 回车 m_pComData->m_ucProtocalTxt[m_pComData->m_unDataLen-1]=0x0A; //LF 换行 } /* int CModBus::ToHexAscII(unsigned int unValue,unsigned char &ucBuff) { unsigned char ucByteL=0; unsigned char ucByteH=0; ucByteH=(unsigned char)unValue>>4; ucByteL=(unsigned char)unValue & 0x00FF ; if(ucByteH>=10) //0x0A ucByteH=ucByteH+'A'-10; else ucByteH+='0'; if(ucByteL>=10) //0x0A ucByteL=ucByteL+'A'-10; else ucByteL+='0'; unsigned char* pucBuff=&ucBuff; *pucBuff=ucByteH; *(++pucBuff)=ucByteL; return 2; } //*/ int CModBus::ToHexAscII(unsigned short usValue,unsigned char &ucBuff) { unsigned char ucByteL=usValue>>8; unsigned char ucByteH=usValue & 0x00FF; ToHexAscII(ucByteL,ucBuff); unsigned char* pucBuff2=&ucBuff+2; ToHexAscII(ucByteH,*pucBuff2); return 4; } int CModBus::ToHexAscII(unsigned char ucByte,unsigned char &ucBuff) { unsigned char ucByteL=0; unsigned char ucByteH=0; ucByteH=(unsigned char)ucByte>>4; ucByteL=(unsigned char)ucByte & 0x0F ; if(ucByteH>=10) //0x0A ucByteH=ucByteH+'A'-10; else ucByteH+='0'; if(ucByteL>=10) //0x0A ucByteL=ucByteL+'A'-10; else ucByteL+='0'; unsigned char* pucBuff=&ucBuff; *pucBuff=ucByteH; *(++pucBuff)=ucByteL; return 2; } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_ASCII_ReadCoils------处理发送字符 //(读取单个/多个线圈DO) 功能代码:0x01 //---------------------------------------------------- //参数: CComData& Data-------------发送数据 //---------------------------------------------------- //功能: 对发送数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_ASCII_ReadCoils(CComData& Data) { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | LRC CHECK | END //--------------------------------------------------------------------------------- // 1 CHAR: | 2 CHARS | 2 CHARS | n CHARS | 2 CHARS | CR LF //--------------------------------------------------------------------------------- //1、功能代码[2 Byte] m_pComData->m_ucProtocalTxt[3]='0'; m_pComData->m_ucProtocalTxt[4]='1'; //2、起始地址[4 Byte] unsigned short usRegAddr=m_pComData->m_unRegAddr; ToHexAscII(usRegAddr, m_pComData->m_ucProtocalTxt[5]); //3、读写寄存器数量[2 Byte] unsigned short usCount=(unsigned short) Data.m_unRegCount; if (0==usCount) usCount=1; ToHexAscII(usCount, m_pComData->m_ucProtocalTxt[9]); //4、数据长度 //--------------------------------------------------------- //1Byte 头 //--------------------------------------------------------- //2Byte 站号 //--------------------------------------------------------- //2Byte Function Code //4Byte Starting Address(0x0000 to 0xFFFF) //4Byte Quantity of coils(1 to 2000(0x7D0)) //--------------------------------------------------------- //2Byte LRC //--------------------------------------------------------- //2Byte END-- CR LF //--------------------------------------------------------- m_pComData->m_unDataLen=17; //2(LRC)+2(END) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_ASCII_ReadDiscreteInputs------处理发送字符 //(读取单个/多个接触器DI) //功能代码:0x02 //---------------------------------------------------- //参数: CComData& Data-------------发送数据 //---------------------------------------------------- //功能: 对发送数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_ASCII_ReadDiscreteInputs(CComData& Data) //功能代码:0x02 { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | LRC CHECK | END //--------------------------------------------------------------------------------- // 1 CHAR: | 2 CHARS | 2 CHARS | n CHARS | 2 CHARS | CR LF //--------------------------------------------------------------------------------- //1、功能代码[2 Byte] m_pComData->m_ucProtocalTxt[3]='0'; m_pComData->m_ucProtocalTxt[4]='2'; //2、起始地址[4 Byte] unsigned short usRegAddr=m_pComData->m_unRegAddr; ToHexAscII(usRegAddr, m_pComData->m_ucProtocalTxt[5]); //3、读写寄存器数量[2 Byte] unsigned short usCount=(unsigned short) Data.m_unRegCount; if (0==usCount) usCount=1; ToHexAscII(usCount, m_pComData->m_ucProtocalTxt[9]); //4、数据长度 //--------------------------------------------------------- //2Byte 站号 //--------------------------------------------------------- //2Byte Function Code //4Byte Starting Address(0x0000 to 0xFFFF) //4Byte Quantity of coils(1 to 2000(0x7D0)) //--------------------------------------------------------- //2Byte LRC //--------------------------------------------------------- //2Byte END-- CR LF //--------------------------------------------------------- m_pComData->m_unDataLen=17; //2(LRC)+2(END) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_ASCII_ReadHoldingRegisters------处理发送字符 //(读取单个/多个保持寄存器) //功能代码:0x03 //---------------------------------------------------- //参数: CComData& Data-------------发送数据 //---------------------------------------------------- //功能: 对发送数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_ASCII_ReadHoldingRegisters(CComData& Data) //功能代码:0x03 { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | LRC CHECK | END //--------------------------------------------------------------------------------- // 1 CHAR: | 2 CHARS | 2 CHARS | n CHARS | 2 CHARS | CR LF //--------------------------------------------------------------------------------- //1、功能代码[2 Byte] m_pComData->m_ucProtocalTxt[3]='0'; m_pComData->m_ucProtocalTxt[4]='3'; //2、起始地址[4 Byte] unsigned short usRegAddr=m_pComData->m_unRegAddr; ToHexAscII(usRegAddr, m_pComData->m_ucProtocalTxt[5]); //3、读写寄存器数量[2 Byte] unsigned short usCount=(unsigned short) Data.m_unRegCount; if (0==usCount) usCount=1; ToHexAscII(usCount, m_pComData->m_ucProtocalTxt[9]); //4、数据长度 //--------------------------------------------------------- //2Byte 站号 //--------------------------------------------------------- //2Byte Function Code //4Byte Starting Address(0x0000 to 0xFFFF) //4Byte Quantity of coils(1 to 2000(0x7D0)) //--------------------------------------------------------- //2Byte LRC //--------------------------------------------------------- //2Byte END-- CR LF //--------------------------------------------------------- m_pComData->m_unDataLen=17; //2(LRC)+2(END) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_ASCII_ReadInputRegisters------处理接收字符 //(读取单个、多个寄存器) //功能代码:0x04 //---------------------------------------------------- //参数: CComData& Data-------------发送的数据 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_ASCII_ReadInputRegisters(CComData& Data) //功能代码:0x04 { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | LRC CHECK | END //--------------------------------------------------------------------------------- // 1 CHAR: | 2 CHARS | 2 CHARS | n CHARS | 2 CHARS | CR LF //--------------------------------------------------------------------------------- //1、功能代码[2 Byte] m_pComData->m_ucProtocalTxt[3]='0'; m_pComData->m_ucProtocalTxt[4]='4'; //2、起始地址[4 Byte] unsigned short usRegAddr=m_pComData->m_unRegAddr; ToHexAscII(usRegAddr, m_pComData->m_ucProtocalTxt[5]); //3、读写寄存器数量[2 Byte] unsigned short usCount=(unsigned short) Data.m_unRegCount; if (0==usCount) usCount=1; ToHexAscII(usCount, m_pComData->m_ucProtocalTxt[9]); //4、数据长度 //--------------------------------------------------------- //2Byte 站号 //--------------------------------------------------------- //2Byte Function Code //4Byte Starting Address(0x0000 to 0xFFFF) //4Byte Quantity of coils(1 to 2000(0x7D0)) //--------------------------------------------------------- //2Byte LRC //--------------------------------------------------------- //2Byte END-- CR LF //--------------------------------------------------------- m_pComData->m_unDataLen=17; //2(LRC)+2(END) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_ASCII_WriteSingleCoil------处理接收字符 //(写单个线圈) //功能代码:0x05 //---------------------------------------------------- //参数: CComData& Data-------------发送的数据 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_ASCII_WriteSingleCoil(CComData& Data) //功能代码:0x05 { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | LRC CHECK | END //--------------------------------------------------------------------------------- // 1 CHAR: | 2 CHARS | 2 CHARS | n CHARS | 2 CHARS | CR LF //--------------------------------------------------------------------------------- //1、功能代码[2 Byte] m_pComData->m_ucProtocalTxt[3]='0'; m_pComData->m_ucProtocalTxt[4]='5'; //2、起始地址[4 Byte] unsigned short usRegAddr=m_pComData->m_unRegAddr; ToHexAscII(usRegAddr, m_pComData->m_ucProtocalTxt[5]); //3、写入值[2 Byte] unsigned short usValue=(unsigned short) atoi(Data.m_strRegValue); if(usValue==1) { //ON m_pComData->m_ucProtocalTxt[ 9]='F'; m_pComData->m_ucProtocalTxt[10]='F'; m_pComData->m_ucProtocalTxt[11]='0'; m_pComData->m_ucProtocalTxt[12]='0'; } else { //OFF m_pComData->m_ucProtocalTxt[ 9]='0'; m_pComData->m_ucProtocalTxt[10]='0'; m_pComData->m_ucProtocalTxt[11]='0'; m_pComData->m_ucProtocalTxt[12]='0'; } //4、数据长度 //--------------------------------------------------------- //2Byte 站号 //--------------------------------------------------------- //2Byte Function Code //4Byte Starting Address(0x0000 to 0xFFFF) //4Byte Quantity of coils(1 to 2000(0x7D0)) //--------------------------------------------------------- //2Byte LRC //--------------------------------------------------------- //2Byte END-- CR LF //--------------------------------------------------------- m_pComData->m_unDataLen=17; //2(LRC)+2(END) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_ASCII_WriteSingleRegister------处理接收字符 //(写单个寄存器) //功能代码:0x06 //---------------------------------------------------- //参数: CComData& Data-------------发送的数据 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_ASCII_WriteSingleRegister(CComData& Data) //功能代码:0x06 { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA | LRC CHECK | END //--------------------------------------------------------------------------------- // 1 CHAR: | 2 CHARS | 2 CHARS | n CHARS | 2 CHARS | CR LF //--------------------------------------------------------------------------------- //1、功能代码[2 Byte] m_pComData->m_ucProtocalTxt[3]='0'; m_pComData->m_ucProtocalTxt[4]='6'; //2、起始地址[4 Byte] unsigned short usRegAddr=m_pComData->m_unRegAddr; ToHexAscII(usRegAddr, m_pComData->m_ucProtocalTxt[5]); //3、写入值[2 Byte] //整形 unsigned short usValue=(unsigned short) atoi(Data.m_strRegValue); ToHexAscII(usValue, m_pComData->m_ucProtocalTxt[9]); //4、数据长度 //--------------------------------------------------------- //2Byte 站号 //--------------------------------------------------------- //2Byte Function Code //4Byte Starting Address(0x0000 to 0xFFFF) //4Byte Quantity of coils(1 to 2000(0x7D0)) //--------------------------------------------------------- //2Byte LRC //--------------------------------------------------------- //2Byte END-- CR LF //--------------------------------------------------------- m_pComData->m_unDataLen=17; //2(LRC)+2(END) } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_ASCII_WriteMultipleCoils------处理接收字符 //(写多个线圈) //功能代码:0x0F //---------------------------------------------------- //参数: CComData& Data-------------发送的数据 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_ASCII_WriteMultipleCoils(CComData& Data) //功能代码:0x0F //十六进制字符串 { //暂不支持 throw("ModBus----(写多个线圈) 功能代码:0x0F,不支持"); } //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ //名称: Query_RTU_WriteMultipleRegisters------处理接收字符(写多个寄存器) //功能代码:0x10 //---------------------------------------------------- //参数: CComData& Data-------------发送的数据 //---------------------------------------------------- //功能: 对接收到的数据进行译码 //---------------------------------------------------- //返回值: // //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ void CModBus::Query_ASCII_WriteMultipleRegisters(CComData& Data) //功能代码:0x10 //十六进制字符串 { //暂不支持 throw("ModBus----(写多个寄存器) 功能代码:0x10,不支持"); } int CModBus::Response_ASCII_ReadCoils(unsigned char& ch) { //--------------------------------------------------------------------------------- // START | ADDRESS | FUNCTION | DATA LEN | DATA | LRC CHECK | END //--------------------------------------------------------------------------------- // 1 CHAR: | 2 CHARS | 2 CHARS | 2 CHARS | n CHARS | 2 CHARS | CR LF //--------------------------------------------------------------------------------- // 0 | 1 - 2 | 3 - 4 | 5 - 6 | 6+n | | //--------------------------------------------------------------------------------- //Read_DO if(5==m_unNowRLen-1) //3-4 byte:功能代码 { m_ucRFunctionCode=(unsigned char)ToHexDec(m_ucRData[3],2); return 0; } else if(7==m_unNowRLen-1) //已经接收字符长度 {//接收到的第一个字符 if(0x01==m_ucRFunctionCode) { int nRData=ToHexDec(m_ucRData[5],2); m_unRLen=7+nRData*2+4; //将要接收字符长度=头(1)+站号(2)+功能代码(2)+数量(2)+数据(N*2)+校验(2)+END(2) return 0; } else if(0x81==m_ucRFunctionCode) {//返回错误----Error=0x01 or 0x02 or 0x03 or 0x04 Error(ch,0x01,m_pComData->m_unRegAddr); return ch; } else {//返回错误----功能代号错误 Error(ch,0x01,m_pComData->m_unRegAddr); return 0; } } //校验码 if(m_unNowRLen==m_unRLen) //字符接收完毕 { m_usRCheck=(unsigned short)ToHexDec(m_ucRData[m_unRLen-4],2); //校验码 //进行LRC校验 unsigned short usCheckCRC16=LRC(&m_ucRData[1],m_unRLen-4); if(usCheckCRC16==m_usRCheck) { //数据传输正确 if(1==m_ucRData[2]) //单个点 // m_pComData->Transform(&m_ucRData[3],1,true); m_pComData->Transform(&m_ucRData[3],1); else Response_RTU_MVaule(3,m_unRLen-2); //需要转换 return 1; } else { //校验码错误 Error(ch,0x01,m_pComData->m_unRegAddr); return 3; } } return 0; //--------------------------------------------------------- } int CModBus::Response_ASCII_ReadDiscreteInputs(unsigned char& ch) { int nReturn=0; return nReturn; } int CModBus::Response_ASCII_ReadHoldingRegisters(unsigned char& ch) { int nReturn=0; return nReturn; } int CModBus::Response_ASCII_ReadInputRegisters(unsigned char& ch) { int nReturn=0; return nReturn; } int CModBus::Response_ASCII_WriteSingleCoil(unsigned char& ch) { int nReturn=0; return nReturn; } int CModBus::Response_ASCII_WriteSingleRegister(unsigned char& ch) { int nReturn=0; return nReturn; } int CModBus::ReceiveByte_RTU(unsigned char& ch) { int nReturn=0; //2、协议数据单元 switch(m_pComData->m_unRegType) { case 1: { nReturn=Response_RTU_ReadCoils(ch); break; } case 2: { nReturn=Response_RTU_ReadDiscreteInputs(ch); break; } case 3: { nReturn=Response_RTU_ReadHoldingRegisters(ch); break; } case 4: { nReturn=Response_RTU_ReadInputRegisters(ch); break; } case 5: { nReturn=Response_RTU_WriteSingleCoil(ch); break; } case 6: { nReturn=Response_RTU_WriteSingleRegister(ch); break; } case 15: { nReturn=Response_RTU_WriteMultipleCoils(ch); break; } case 16: { nReturn=Response_RTU_WriteMultipleRegisters(ch); break; } default: { //功能代码错误 break; // } } if(0<nReturn) m_pComData=NULL; return nReturn; } int CModBus::ReceiveByte_ASCII(unsigned char& ch) { int nReturn=0; //RLen: //1 数据帧头:':' //2-3 站号 // if(3<=m_unNowRLen) return nReturn; //2、协议数据单元 switch(m_pComData->m_unRegType) { case 1: { nReturn=Response_ASCII_ReadCoils(ch); break; } case 2: { nReturn=Response_ASCII_ReadDiscreteInputs(ch); break; } case 3: { nReturn=Response_ASCII_ReadHoldingRegisters(ch); break; } case 4: { nReturn=Response_ASCII_ReadInputRegisters(ch); break; } case 5: { nReturn=Response_ASCII_WriteSingleCoil(ch); break; } case 6: { nReturn=Response_ASCII_WriteSingleRegister(ch); break; } case 15: { // nReturn=Response_ASCII_WriteMultipleCoils(ch); break; } case 16: { // nReturn=Response_ASCII_WriteMultipleRegisters(ch); break; } default: { //功能代码错误 break; // } } if(0<nReturn) m_pComData=NULL; return nReturn; } long CModBus::ToHexDec(unsigned char &ucBuff,int nLen) const { long nValue=0; if(nLen>8) return nValue; char cBuf[10]; cBuf[nLen]='\0'; unsigned char * pucVal=NULL; for(int n=0;n<nLen;n++) { pucVal=&ucBuff+n; cBuf[n]=*pucVal; } sscanf(cBuf,"%x",& nValue); return nValue; }